import json
import datetime
import time

from django.core.paginator import Paginator
from django.db.models import Q
from django.shortcuts import render
from django.http import JsonResponse

# Create your views here.
from django.views import View

from AiJiaHome.utils.fastdfs.fastdfs_storage import FastDFSStorage
from AiJiaHome.utils.response_code import RET
from AiJiaHome.utils.views import LoginRequiredJSONMixin
from addresses.models import Area
from houses import constants
from houses.models import House, Facility, HouseImage
from orders.models import Order


class HouseSearchView(View):
    '''搜索房屋'''

    def get(self, request):
        # 搜索房屋
        # 接收参数
        aid = request.GET.get('aid')  # 区域id
        sd = request.GET.get('sd')  # 开始日期
        ed = request.GET.get('ed')  # 结束时间
        # 最新上线new(上线时间)排序方式booking(订单量), price-inc(低到高), price-des(高到低)
        sk = request.GET.get('sk')
        p = request.GET.get('p', 1)  # 页数
        # 检验参数
        if not all([aid, sd, ed, sk, p]):
            return JsonResponse({'errno': RET.DATAERR, 'errmsg': "缺少必传参数"})
        try:
            sd = time.strptime(sd, "%Y-%m-%d")
            sd = int(time.mktime(sd))
            ed = time.strptime(ed, "%Y-%m-%d")
            ed = int(time.mktime(ed))
            days = int(ed - sd)
            days = int(days / (3600 * 24))
            if days <= 0:
                return JsonResponse({"errno": RET.DATAERR, "errmsg": "日期错误"})
        except Exception:
            return JsonResponse({'errno': RET.DATAERR, 'errmsg': "日期错误"})
        try:
            area = Area.objects.get(id=aid)
            houses = House.objects.filter(area=area).filter(min_days__lte=days).filter(Q(max_days__gte=days) | Q(max_days=0))
            if sk == 'new':
                houses = houses.order_by('-create_time')
            elif sk == 'booking':
                houses = houses.order_by('-order_count')
            elif sk == 'price-inc':
                houses = houses.order_by('price')
            elif sk == 'price-des':
                houses = houses.order_by('-price')
            else:
                return JsonResponse({'errmsg': '参数错误', 'errno': RET.DATAERR})

            house_list = []
            for house in houses:
                # 确认房屋未被预定
                orders = Order.objects.filter(house=house).exclude(status='REJECTED').exclude(status='CANCELED')
                house_order = True
                for order in orders:
                    begin_time = int(time.mktime(time.strptime(str(order.begin_date)[:10], "%Y-%m-%d")))
                    end_time = int(time.mktime(time.strptime(str(order.end_date)[:10], "%Y-%m-%d")))
                    if not(ed < begin_time or sd > end_time):
                        house_order = False
                        break

                if house_order:
                    house_list.append({
                        'house_id': house.id,
                        'order_count': house.order_count,
                        'title': house.title,
                        'ctime': (str(house.create_time))[:10],
                        'price': house.price,
                        'area_name': house.area.name,
                        'address': house.address,
                        'room_count': house.room_count,
                        'img_url': house.index_image_url,
                        'user_avatar': house.user.avatar_url,
                    })
        except Exception:
            return JsonResponse({'errmsg': '请求数据库错误', 'errno': RET.DBERR})

        # 获取分页器
        paginator = Paginator(house_list, constants.GOODS_LIST_LIMIT)
        # 分页后的数据
        page_houses = paginator.page(p).object_list
        # 获取总页数
        total_page = paginator.num_pages
        context = {'houses': page_houses, 'total_page': total_page}
        return JsonResponse({'data': context, 'errmsg': '请求成功', 'errno': RET.OK})


class IndexHouseView(View):
    '''首页房屋推荐'''

    def get(self, request):
        # 首页推荐房屋

        context = []
        try:
            houses = House.objects.order_by('-create_time')[:5]
            for house in houses:
                context.append({
                    'house_id': house.id,
                    'img_url': house.index_image_url,
                    'title': house.title
                })
        except Exception:
            return JsonResponse({'errno': RET.DBERR, 'errmsg': "请求数据库失败"})
        # 返回参数
        return JsonResponse({'data': context, 'errmsg': 'OK', 'errno': RET.OK})


class HouseInfoView(View):
    '''房屋信息'''

    def get(self, request, house_id):
        '''获取房屋信息'''

        user = request.user
        try:
            house = House.objects.get(id=house_id)
            # 获得该房屋的所有评论
            orders = Order.objects.filter(house=house).filter(status='COMPLETE')
            comment_list = []
            for order in orders:
                comment_list.append({
                    "comment": order.comment,
                    "ctime": (str(order.create_time))[:10],
                    "user_name": order.user.username
                })
            # 获取房屋的图片
            img_urls = HouseImage.objects.filter(house=house)
            img_urls_list = []
            for img_url in img_urls:
                img_urls_list.append(img_url.url)
            # 获得房屋信息
            facility_list = []
            facilities = house.facilities.all()
            for facility in facilities:
                facility_list.append(facility.id)
        except Exception:
            return JsonResponse({'errno': RET.DBERR, 'errmsg': "请求数据库失败"})

        # 拼接参数
        house_dict = {
            "acreage": house.acreage,
            "address": house.address,
            "beds": house.beds,
            "capacity": house.capacity,
            "comments": comment_list,
            "deposit": house.deposit,
            "facilities": facility_list,
            "hid": house.id,
            "img_urls": img_urls_list,
            "max_days": house.max_days,
            "min_days": house.min_days,
            "price": house.price,
            "room_count": house.room_count,
            "title": house.title,
            "unit": house.unit,
            "user_avatar": house.user.avatar_url,
            "user_id": house.user.id,
            "user_name": house.user.username
        }

        context = {
            "house": house_dict,
            "user_id": user.id
        }

        # 返回参数
        return JsonResponse({"errmsg": "OK", "errno": RET.OK, "data": context})


class MyHouseImageView(LoginRequiredJSONMixin, View):

    def post(self, request, house_id):
        house_image = request.FILES.get('house_image')
        # 上传用户图片
        try:
            file_id = FastDFSStorage().save(house_image.name, house_image)
            url = FastDFSStorage().url(file_id)
        except Exception:
            return JsonResponse({"errno": RET.DBERR, "errmsg": "上传失败"})

        # 保存用户头像
        try:
            house = House.objects.get(id=house_id)

            # 保存房屋图片
            if house.index_image_url == '':
                house.index_image_url = url
                HouseImage.objects.create(house=house, url=url)
                house.save()
            else:
                HouseImage.objects.create(house=house, url=url)
        except Exception:
            return JsonResponse({"errno": RET.DBERR, "errmsg": "上传失败"})
        return JsonResponse({'errno': RET.OK, 'errmsg': "OK", 'data': {"url": url}})


class MyNewHouseView(LoginRequiredJSONMixin, View):
    '''发布新房源'''

    def post(self, request):
        '''发布新房源'''
        # 接收参数
        json_dict = json.loads(request.body.decode())
        title = json_dict.get('title')
        price = json_dict.get('price')
        area_id = json_dict.get('area_id')
        address = json_dict.get('address')
        room_count = json_dict.get('room_count')
        acreage = json_dict.get('acreage')
        unit = json_dict.get('unit')
        capacity = json_dict.get('capacity')
        beds = json_dict.get('beds')
        deposit = json_dict.get('deposit')
        min_days = json_dict.get('min_days')
        max_days = json_dict.get('max_days')
        facilities = json_dict.get('facility')
        # 检验参数
        if not all([title, price, area_id, address, room_count, acreage, unit, capacity, beds, deposit, min_days,
                    max_days]):
            return JsonResponse({'errno': RET.DATAERR, 'errmsg': "缺少参数"})
        # 保存参数
        try:
            house = House.objects.create(user=request.user,
                                         title=title,
                                         price=price,
                                         area_id=area_id,
                                         address=address,
                                         room_count=room_count,
                                         acreage=acreage,
                                         unit=unit,
                                         capacity=capacity,
                                         beds=beds,
                                         deposit=deposit,
                                         min_days=min_days,
                                         max_days=max_days)

            # 保存多对多设备信息
            facilities = Facility.objects.filter(id__in=facilities)
            house.facilities.add(*facilities)
            house.save()
        except:
            return JsonResponse({'errno': RET.DBERR, 'errmsg': "保存失败"})
        # 返回参数
        return JsonResponse({'errno': RET.OK, 'errmsg': "Ok", 'data': {"house_id": house.id}})


class UserMyHousesView(LoginRequiredJSONMixin, View):
    '''获取我的房源'''

    def get(self, request):
        '''获取我的房源'''
        # 接收参数
        user = request.user
        try:
            houses = House.objects.filter(user=user)
            houses_list = []
            for house in houses:
                houses_list.append({
                    'address': house.address,
                    'area_name': house.area.name,
                    'ctime': (str(house.create_time))[:10],
                    'house_id': house.id,
                    'img_url': house.index_image_url,
                    'order_count': house.order_count,
                    'price': house.price,
                    'room_count': house.room_count,
                    'title': house.title,
                    'user_avatar': house.user.avatar_url,
                })
        except Exception:
            return JsonResponse({'errno': RET.DBERR, 'errmsg': "请求数据库失败"})

        return JsonResponse({'data': houses_list, 'errmsg': 'OK', 'errno': RET.OK})
